// Platform.cpp : main source file for Platform.exe
//

#include "stdafx.h"
#include "resource.h"
#include "Module.h"
#include "Platform.h"
#include "MainFrm.h"

#include <XLib/XSocket.h>

//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////

PlatformModule::PlatformModule()
{

}

PlatformModule::~PlatformModule()
{

}

HRESULT PlatformModule::Init(ATL::_ATL_OBJMAP_ENTRY* pObjMap, HINSTANCE hInstance, const GUID* pLibID/* = NULL*/)
{
	HRESULT hr = Base::Init(pObjMap,hInstance,pLibID);
	XLibInit::Init();
	LogInfo(_T("PlatformModule::Init"));
	return hr;
}

void PlatformModule::Term()
{
	LogInfo(_T("PlatformModule::Term"));
	FreeAllLibrary();
	XLibInit::Release();
	Base::Term();
}

HMODULE PlatformModule::LoadLibrary(LPCTSTR lpFileName)
{
	SectionLocker Lock(&m_Section);
	HMODULE hModule = NULL;
	CString strModule = lpFileName;
	std::map<CString,HMODULE,CStringNoCaseLess>::iterator it = m_mapModule.find(strModule);
	if (it!=m_mapModule.end()) {
		hModule = it->second;
	}
	if (!hModule) {
		LogInfo(_T("PlatformModule::LoadLibrary ")+strModule);
		hModule = ::LoadLibrary(strModule);
		m_mapModule[strModule] = hModule;
	}
	return hModule;
}
//
//BOOL PlatformModule::FreeLibrary(HMODULE hModule)
//{
//	return FALSE;
//}

void PlatformModule::FreeAllLibrary()
{
	SectionLocker Lock(&m_Section);
	std::map<CString,HMODULE,CStringNoCaseLess>::iterator it = m_mapModule.begin();
	for (; it!=m_mapModule.end(); ++it)
	{
		LogInfo(_T("PlatformModule::FreeLibrary ")+it->first);
		::FreeLibrary(it->second);
	}
	m_mapModule.clear();
}

PlatformModule _Module;

//////////////////////////////////////////////////////////////////////////

#if USES_MULTITHREAD

// thread init param
struct _RunData
{
	CString strName;
	CString strCmdLine;
	int nCmdShow;
};

// thread proc
static DWORD WINAPI RunThread(LPVOID lpData)
{
	UIEvtMessageLoop theLoop;
	_Module.AddMessageLoop(&theLoop);

	USES_CONVERSION;

	_RunData* pData = (_RunData*)lpData;
	CMainFrame wndMain(pData->strName,pData->strCmdLine);
	if(wndMain.CreateEx() == NULL) {
		ATLTRACE(_T("Main window creation failed!\n"));
		return 0;
	}
	wndMain.ShowWindow(pData->nCmdShow);
	::SetForegroundWindow(wndMain);	// Win95 needs this
	delete pData;

	int nRet = theLoop.Run();

	_Module.RemoveMessageLoop();
	return nRet;
}

CMultiThreadThreadManager::CMultiThreadThreadManager()
{

}

// Operations
HANDLE CMultiThreadThreadManager::AddThread(LPCTSTR lpstrName, LPCTSTR lpstrCmdLine, int nCmdShow)
{
	_RunData* pData = new _RunData;
	pData->strName = lpstrName;
	pData->strCmdLine = lpstrCmdLine;
	pData->nCmdShow = nCmdShow;
	DWORD dwThreadID;
	HANDLE hThread = ::CreateThread(NULL, 0, RunThread, pData, 0, &dwThreadID);
	if(hThread == NULL)
	{
		::MessageBox(NULL, _T("ERROR: Cannot create thread!!!"), _T("MultiThread"), MB_OK);
		return 0;
	}

	return hThread;
	//return dwThreadID;
}

CMultiThreadThreadManager _MultiThreadMgr;

#endif//

